#include "can.h"
CAN::CAN(const std::string& device , int baudrate)
{
    this -> can_device = device;
    std::stringstream ss;
    ss << "sudo ip link set " << device << " down";
    system(ss.str().c_str()); // 使用 stringstream 构建命令并转换为 const char*
    ss.str("");

    ss << "sudo ip link set " << device << " type can bitrate " << std::to_string(baudrate);
    system(ss.str().c_str()); // 使用 stringstream 构建命令并转换为 const char*
    ss.str("");

    ss << "sudo ip link set " << device << " up";
    system(ss.str().c_str()); // 使用 stringstream 构建命令并转换为 const char*
    ss.str("");
    // 创建 CAN 套接字
    if ((socket_ = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
    {
        perror("Socket creation failed");
        exit(-1);
    }

    // 设置接口名称（例如 can0）
    strcpy(ifr.ifr_name, device.c_str());
    ioctl(socket_, SIOCGIFINDEX, &ifr);

    // 设置套接字地址
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    // 绑定套接字到指定的 CAN 接口
    if (bind(socket_, (sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("Bind failed");
        exit(-1);
    }
    running_ = 1;
    recv_thread = std::thread(&CAN::receive, this);
}
CAN::~CAN()
{
    close(socket_);
    running_ = 0;
    recv_thread.join();
    std::stringstream ss;
    ss << "sudo ip link set " << can_device << " down";
    system(ss.str().c_str());
}
void CAN::send(const can_frame &frame_)
{
    if (write(socket_, &frame_, sizeof(frame_)) != sizeof(frame_)) {
        std::stringstream ss;
        ss << "Write failed " << can_device ;
        perror(ss.str().c_str());
    } else {
        std::cout << "Sent extended CAN frame: ID=" << std::hex << frame_.can_id
                  << " Data=";
        for (size_t i = 0; i < frame_.can_dlc; ++i) {
            std::cout << " " << std::hex << static_cast<int>(frame_.data[i]);
        }
        std::cout << std::endl;
    }
    // write(socket_, &frame_, sizeof(frame_));
}
can_frame CAN::get_receive_frame()
{
    return receive_frame.load();
}
void CAN::receive()
{
    can_frame _;
    int receive_;
    // auto t = std::chrono::high_resolution_clock::now();

    while (running_)
    {
        //输出时间差
        // std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t).count() << "ms" << std::endl;
        // t = std::chrono::high_resolution_clock::now();
        receive_ = read(socket_, &_, sizeof(can_frame)); // 接收报文
        // 显示报文
        if (receive_ > 0)
        {
            if(receive_callback != NULL)receive_callback(_);
            memcpy(&receive_frame, &_, sizeof(can_frame));
            // std::cout << "Received CAN frame: ID=" << (u_int16_t)_.can_id - 2304 << std::endl;
                    //   << " Data=";
        }
    }
}
void CAN::set_Callback(std::function<void(const can_frame& frame)> slot){
    receive_callback = slot;
}
